package dfbz.手写ArrayList;
/*
 *  MyList:
 *     1.boolean add(E e)
 *     2.E get(int index)
 *     3.E remove(int index)
 *     4.int size（）
 *     5. boolean isEmpty()
 *     6.void clear()
 *     7. String toString
 *     8.E set(int index,E e)
 *
 * */

import java.util.Arrays;

public class MyList<E> {
    //默认容量
    private int DEFAULT_CAPACITY = 10;
    //底层存放元素的数组
    private Object[] elementData = {};
    //通过构造方法创建集合时初始化的数组对象
    private Object[] DEFAULT_DATA = {};
    //集合的长度
    private int size;

    public MyList() {
        this(0);
    }

    public MyList(int size) {
        if (size < 0) {
            throw new IllegalArgumentException("长度不规范");
        } else if (size == 0) {
            elementData = DEFAULT_DATA;
        } else {
            elementData = new Object[size];
        }
    }

    //添加数组
    public boolean add(E e) {// E e
        //检测容量时候足够
        ensureCapacityInternal(size + 1);
        //底层数组的长度先用后加
        elementData[size++] = e;
        return true;
    }

    //检查容量是否足够 传入参数为最小容量
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private int ensureExplicitCapacity(int minCapacity) {
        if (minCapacity - elementData.length > 0) { //如果最小的长度-底层数组的长度>0则会进行扩容
            grow(minCapacity);
        }
        return minCapacity;
    }

    private int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULT_DATA) {
            return minCapacity > DEFAULT_CAPACITY ? minCapacity : DEFAULT_CAPACITY;
        }
        return minCapacity;
    }

    //对数组进行扩容
    private void grow(int minCapacity) {
        //定义一个旧的数组的容量
        int OldCapacity = elementData.length;
        int newCapacity = OldCapacity + (OldCapacity / 2);//新的长度等于=旧的容量的1.5倍
        if (newCapacity - minCapacity < 0) { //如果新的-最小的容量还<0  ,将最小的容量赋值给新的容量
            newCapacity = minCapacity;
        }
        elementData = Arrays.copyOf(elementData, newCapacity);//将底层数组复制,将最新的容量复制给数组
    }

    public E remove(int index) {
        //检查索引是否越界
        reChark(index);
        //取出旧的索引
        E oldValue = getEle(index);
        //计算复制数组中的个数
        int numMoved = size - index - 1;
        if (numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--index] = null;
        return oldValue;
    }

    private void reChark(int index) {
        if (index > elementData.length) {
            throw new IndexOutOfBoundsException("索引越界异常");
        }
    }

    //获取元素的方法
    public E getEle(int index) {
        return (E) elementData[index];
    }

    //判断是否越界
    private void rangeCheck(int index) {
        if (index >= size) {
            //报异常
            throw new IndexOutOfBoundsException("索引越界异常");
        }
    }

    //获得数组大小
    public int size() {
        checkForComodification();
        return this.size;
    }

    private void checkForComodification() {
        if (elementData.length < 0) {
            throw new IndexOutOfBoundsException("数组为空");
        }
    }

    //get方法
    public E get(int index) {
        rangeCheck(index);
        return getEle(index);
//        return (E) elementData[index];
    }

    //toString
    public String toString() {
        return "MyList{" +
                "elementData=" + Arrays.toString(elementData) +
                ", size=" + size +
                '}';
    }

    //判断是否为空 空 则为true  否则 false
    public boolean isEmpty() {
        if (elementData.length == 0) {
            return true;
        }
        return false;
    }
    //set方法。
    public E set(int index, E e) {
        E e1= (E) elementData[index];
        elementData[index]=e;
        return e1;
    }


}
